查看原文
其他

Unity《Boat Attack》Demo幕后揭秘(内附源码下载)

Unity Unity官方平台 2022-05-07

通用渲染管线是一款强大的,包含一系列艺术创作工具的产品级图像制作解决方案。若希望制作出具有顶尖质量的图像,将项目发布到所有Unity支持平台上,通用渲染管线是一个不错的选择。本文中,我们一起来看看使用通用渲染管线制作《Boat Attack》Demo的过程 。

 

我们最初制作《Boat Attack》演示项目是为了验证和测试通用渲染管线的性能(当时还叫轻量渲染管线)。在开发时制作的这个垂直切片式演示,也是一次生产流程实地操作的练习。

 

Boat Attack Gameplay Video Demo 2018版


自第一版本的Demo发布以来,我们多次升级了《Boat Attack》演示项目。如今,项目中使用了许多新出的通用渲染管线图像功能,其中包括C# Job System、Burst compiler、Shader Graph、新Input System等等。

 

*本文针对《Boat Attack》demo制作过程的技术介绍篇幅较长,将分为上下两篇逐一介绍。

 

《Boat Attack》Demo 介绍

《Boat Attack》演示项目展示了一款用Unity制作的赛艇游戏。游戏现可供游玩,并且还在不断优化,我们尽量让游戏能完全利用起最新的Unity功能。

 

Demo能够在大部分平台中顺畅运行,包括中高端移动设备,现世代主机和单独的游戏平台App。在2019年的哥本哈根Unite大会上,我们使用了一系列的设备来演示《Boat Attack》,包括iPhone 7、PlayStation 4等等。

 

您可从GitHub上下载该Demo,并在最新版本Unity 2019.3中运行。

 https://github.com/Verasl/BoatAttack

  

Shader Graph


Shader Graph是一款对艺术家十分友好的着色器创作界面,在技术美术的手中,它是一个强大的原型构建工具。在《Boat Attack》中,我们使用了Shader Graph制作出了一些独特的着色器效果。

 

Shader Graph可以制作出超棒的着色器效果,还能方便开发者在各版本的轻量渲染管线和通用渲染管线中维护所有的着色器。

  

《Boat Attack》中展示的峭壁上的着色器通过采集网格元数据制作,Shader Graph可以轻易从网格中提取出各类数据。在峭壁较为平坦的位置、以及朝上的平面上,我们在网格的法线方向上绘制了杂草,同时限定了绘制时的场景空间高度,确保杂草不会被绘制到靠近水面的峭壁和岩块上。

 

自左向右:Y轴高度遮罩、Y轴法线遮罩、高度和法线遮罩重新映射后的效果、最终的着色器

  

植被着色


《Boat Attack》中的植被最初是使用特制的顶点/片元着色器(Vertex/Fragment shader)制作,但由于管线依旧处于早期开发阶段,代码时常会更改,维护植被着色器让人非常头疼。在用Shader Graph重新制作着色器后,更新就变得轻松多了。

 

植被的Shader Graph效果是基于Crytek的Tiago Sousa介绍的技术制作的,该技术很好地利用了顶点色彩的通道,用顶点错位来形成植被的风吹动画。在《Boat Attack》里,我们创建了一个次级图表来囊括进所有风吹动画运算所需的节点。在次级图表中包含了许多嵌套的次级图表,都是用于执行重复性数学运算的图表。

 

单个通道上的顶点动画和遮罩。自左向右:自远到近的主要混合模式,顶点色彩红色通道上的叶片边缘,顶点色彩蓝色通道和绿色通道一起组成植被的相位偏移。

 

在制作逼真植被时,另一个重要的部分是次表面散射(subsurfaceScattering,SSS),遗憾的是通用渲染管线当前并不支持SSS。然而,我们可以使用Shader Graph的自定义功能节点从通用渲染管线中取得光照信息,制作出一种近似SSS的效果。

 


以上是节点布局。SSS Mask部分使用了顶点颜色绿色通道(叶相)和反射率(Albedo)纹理贴图制作。


自定义功能节点可让我们有更多的创作自由。在《Unity通用渲染管线Universal RenderPipeline》中详细了解如何自定义渲染,或者直接从《Boat Attack》的代码库中迁出节点代码,尝试自己的光照设想。

 

自左向右:无SSS,加入SSS,最终着色


自定义船体



 船体有许许多多的色彩供选择。我们使用SubstancePainter绘制了两种船体遮罩,打包储存在了纹理中,它们由Metallic(红色通道)、Smoothness(绿色通道)、Livery 1(蓝色通道)和Livery 2(不透明度)组成。我们可以在Shader Graph中选择性地在遮罩位置应用上不同的颜色。

 


这是船体上色方式的概览。使用覆盖混合可以让较不明显的色彩穿透反射率贴图。

 


这是Shader Graph中的节点布局,全部包括在了一个次级图表中,便于在RaceBoats父图表中使用。

 

房屋



 《Boat Attack》中有完整的日夜循环。为了增加景色的实感,我们为关卡中所有建筑的窗口制作了一个Shader Graph。该图表会在日暮时为窗口添加些许光照,在黎明时去除光照。

  

我们使用了一个简单的发光纹理,根据返回的日夜数值来确定是否要添加贴图。此外,还根据对象的位置加入了打乱纹理排序的效果,让房屋能以不同的顺序被点亮。

 

实现随机发光的节点图

  

云朵



既然在《Boat Attack》中有了光线的变换,简单的高动态范围成像(HDRI)天空盒似乎已不能满足需求。云朵应该动态地受场景光照影响。

 

但大块云朵的实时渲染性能要求太高,对移动端来说尤其如此。因为我们不需要从多个角度观看云朵,所以可以使用带纹理的卡片状云朵来节省性能。

 

当前渲染云朵的图表

 

Shader Graph在构建外观原型时非常关键。我们用Houdini烘焙了部分体积云朵数据,再在Shader Graph中制作了自定义的光照图表。云朵效果仍有待完善,但这表明节点式编辑器也可以制作许多类型的表面。

  

通过API渲染来实现无缝的平面反射


可编程渲染管线的目标是允许用户自定义渲染代码,将代码部分摆到用户的面前。我们并不会简单地打开使用现有的渲染代码,而是不停地添加新的API和硬件支持,将渲染技术带上新的台阶。

 

用户可以使用自己的C#脚本拓展通用渲染管线开箱即用的渲染功能。管线有4个与之相关的API:

 

  • RenderPipelineManager.beginFrameRendering

  • RenderPipelineManager.beginCameraRendering

  • RenderPipelineManager.endCameraRendering

  • RenderPipelineManager.endFrameRendering

 

你可以使用这些挂钩,在系统渲染场景和特定镜头之前,运行自己的代码。在《BoatAttack》中,我们使用了这些API,在主要帧被渲染之前,将场景渲染进纹理,实现了平面反射的效果。


private void OnEnable(){ RenderPipelineManager.beginCameraRendering += ExecutePlanarReflections;}

右滑查看全部内容


由于我们订阅了该API的回调,需要用OnDisable来取消订阅。


我们可以在平面反射脚本中看到入口点。这段代码可在每次通用渲染管线渲染镜头时调用一个自定义方法。这里调用的方法为ExecutePlanarReflections。


public void ExecutePlanarReflections(ScriptableRenderContext context, Camera camera){ //rendering code....}

右滑查看全部内容

 

由于使用的是[beginCameraRendering]回调,必须以一个[ScriptableRenderContext]和一个[Camera]作为参数。这些数据会随着回调一起被导入,方法还会告知渲染的是哪个镜头。


大部分情况下,这里的代码就是应用平面反射的范例了,它处理的是镜头和矩阵。唯一的区别在于,通用渲染管线有用于渲染镜头的新API。


今天的内容就介绍到这里,有关应用平面反射的完整方法我们将在周六的推文中详细介绍

 

推荐阅读

按需渲染如何改善移动端性能?

使用Unity 2019.2最新地形工具加速地形创作

Unite Shanghai 2020正式启动,暖冬特惠票热销中

享受梦幻技术盛宴,相约 Unite 2020

Unity在线学习平台,让梦想不再遥不可及

Unity XR 平台更新,这些变化你不可不知



官方活动


Unite Shanghai 2020暖冬特惠票热销中,现在购票即可获得多款Asset Store特定精品资源5折优惠码。[了解详情......




喜欢本文,请点“在看”



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存